unit uHelpers;

interface

type
  THelperVariant = class

    class function ToString(const a_Variant: Variant): String; overload;

  end;

type
  THelperString = class

    class function Validate_Document_CPF(const a_Doc: String): Boolean;
    class function Validate_Document_CNPJ(const a_Doc: String): Boolean;
    class function ToInteger(const a_Var: String): Integer;

    class procedure ReplaceString(const a_String: String; const a_Old: String; const a_New: String; var a_Variable: String);

  end;


implementation

uses
  Variants, SysUtils;


{ THelper }

class function THelperVariant.ToString(const a_Variant: Variant): String;
begin
  Result := VarToStr(a_Variant);
end;

{ THelperString }

class procedure THelperString.ReplaceString(const a_String, a_Old, a_New: String; var a_Variable: String);
begin
  a_Variable := StringReplace(a_String, a_Old, a_New, [rfReplaceAll]);
end;

class function THelperString.ToInteger(const a_Var: String): Integer;
begin
  Result := StrToInt(a_Var);
end;

class function THelperString.Validate_Document_CNPJ(const a_Doc: String): Boolean;

const c_Digitos: String[25] = '5432987654326543298765432';

var
  t_Ctrl: String[2];
  t_CNPJ: String;

  t_Dig1: Integer;
  t_Dig2: Integer;
  t_I: Integer;

Begin
  THelperString.ReplaceString(a_Doc, '.', '', t_CNPJ);
  THelperString.ReplaceString(t_CNPJ, '-', '', t_CNPJ);
  THelperString.ReplaceString(t_CNPJ, ' ', '', t_CNPJ);
  THelperString.ReplaceString(t_CNPJ, '_', '', t_CNPJ);

  if Length(t_CNPJ) <> 14 then
    begin
      Result := t_CNPJ = '';
      Exit;
    end
  else if (t_CNPJ = '') then
    begin
      Result := True;
      Exit;
    end;

  t_CTRL := Copy(t_CNPJ, Length(t_CNPJ) - 1, 2);
  t_CNPJ := Copy(t_CNPJ, 1, Length(t_CNPJ) - 2);
  t_Dig1 := 0;

  for t_I := 1 to Length(t_CNPJ)
    do t_Dig1 := t_Dig1 + THelperString.ToInteger(t_CNPJ[t_I]) * THelperString.ToInteger(c_Digitos[t_I]);

  t_Dig1 := t_Dig1 mod 11;

  if t_Dig1 in [0, 1]
    then t_Dig1 := 0
    else t_Dig1 := Abs(t_Dig1 - 11);

  t_Dig2 := 0;
  t_CNPJ := t_CNPJ + IntToStr(t_Dig1);

  for t_I := 1 to Length(t_CNPJ)
    do t_Dig2 := t_Dig2 + THelperString.ToInteger(t_CNPJ[t_I]) * THelperString.ToInteger(c_Digitos[t_I + 12]);

  t_Dig2 := t_Dig2 mod 11;

  if t_Dig2 in [0, 1]
    then t_Dig2 := 0
    else t_Dig2 := Abs(t_Dig2 - 11);

  Result := (THelperVariant.ToString(t_Dig1) + THelperVariant.ToString(t_Dig2)) = t_CTRL;
end;

class function THelperString.Validate_Document_CPF(const a_Doc: String): Boolean;
var
  t_Ctrl: String[2];
  t_CPF: String;

  t_CNT: Integer;
  t_Dig1: Integer;
  t_Dig2: Integer;
  t_I: Integer;

Begin
  Result := True;

  THelperString.ReplaceString(a_Doc, '.', '', t_CPF);
  THelperString.ReplaceString(t_CPF, '-', '', t_CPF);
  THelperString.ReplaceString(t_CPF, ' ', '', t_CPF);
  THelperString.ReplaceString(t_CPF, '_', '', t_CPF);

  if Length(t_CPF) <> 11 then
    begin
      Result := t_CPF = '';
      Exit;
    End
  else if (t_CPF = '') then
    begin
      Result := True;
      Exit;
    end;

  t_Dig1 := 0;
  t_Dig2 := 0;
  t_Ctrl := Copy(t_CPF, Length(t_CPF) - 1, 2);
  t_CPF := Copy(t_CPF, 1, Length(t_CPF) - 2);
  t_CNT := 0;

  for t_I := 1 to Length(t_CPF)
    do t_CNT := t_CNT + (11 - t_I) * THelperString.ToInteger(t_CPF[t_I]);

  if (t_CNT mod 11) > 1
    then t_Dig1 := 11 - (t_CNT mod 11);

  t_CNT := 0;

  for t_I := 1 to Length(t_CPF)
    do t_CNT := t_CNT + (12 - t_I) * THelperString.ToInteger(t_CPF[t_I]);

  t_CNT := t_CNT + 2 * t_Dig1;

  if (t_CNT mod 11) > 1
    then t_Dig2 := 11 - (t_CNT mod 11);

  Result := (THelperVariant.ToString(t_Dig1) + THelperVariant.ToString(t_Dig2)) = t_Ctrl;
end;

end.
